#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include "ej3.h"

using namespace std;

#define adentro(p,minx,maxx,miny,maxy) ((p).x >= (minx) && (p).x <= (maxx) && (p).y >= (miny) && (p).y <= (maxy))
//#define GRAFICAR

#ifdef GRAFICAR
#include "timer.h"
static void graficar();
#endif

static Rectangulo solucionar( int b, int h, vector<Point> puntos );

static bool terminar_entrada() {
	while ( isspace( cin.peek() ) )
		cin.get();
	if ( cin.peek() == '#' ) return true;
	if ( cin.eof() ) return true;
	return false;
}

int main( int argc, char **argv ) {
	#ifdef GRAFICAR
	if ( !strcmp( argv[0], "./graficar" ) ||
		!strcmp( argv[0], "graficar" ) ) {
		graficar();
		return 0;
	}
	#endif

	for(;;) {
		int k, b, h;
		vector<Point> puntos;

		if ( terminar_entrada() ) break;

		cin >> k >> b >> h;

		for ( int i = 0; i < k; i++ ) {
			Point p;
			cin >> p.x >> p.y;
			puntos.push_back( p );
		}

		Rectangulo s = solucionar( b, h, puntos );
		cout << s.x << ' ' << s.y << ' ' << s.puntos << endl;
	}

	return 0;
}

#ifdef GRAFICAR
static void graficar() {
	vector<Point> puntos;
	Timer t;
	srand( time( NULL ) );
	static const int max = 1000000;

	for ( int i = 100; i <= max; i += 100 ) {
		for ( int j = 0; j < 100; j++ )
			puntos.push_back( Point( rand() / 16, rand() / 16 ) );
		
		t.start();
		solucionar( RAND_MAX / 4, RAND_MAX / 4, puntos );
		t.stop();

		cout << i << '\t' << t.delta() << '\n';

		cerr << (static_cast<double>(i) * 100.0 / static_cast<double>(max)) << "%\r";
	}
	cerr << endl;
}
#endif

// Solución
static Rectangulo solucionar( int b, int h, vector<Point> puntos ) {
	vector<Point> candidatos;
	int size = puntos.size();
	Rectangulo maximo = { 0, 0, 0 };

	// Recorremos todos los puntos
	for ( int k = 0; k < size; k++ ) {
		int minx = puntos[k].x - b;
		int maxx = puntos[k].x + b;
		int miny = puntos[k].y - h;
		int maxy = puntos[k].y + h;

		// Agregamos todos los puntos que estén
		// dentro del alcance de la caja tomando
		// el punto de referencia.
		candidatos.clear();
		for ( int j = 0; j < size; j++ ) {
			if ( j == k ) continue;
			if ( adentro( puntos[j], minx, maxx, miny, maxy ) )
				candidatos.push_back( puntos[j] );
		}

		// Recorremos todos los candidatos y contamos la
		// cantidad de puntos que quedan dentro de la caja
		vector<Point>::const_iterator it = candidatos.begin();
		vector<Point>::const_iterator end = candidatos.end();
		for ( ; it != end; ++it ) {
			int res = 2;
			// Armamos la caja.
			if ( puntos[k].x < it->x ) {
				minx = puntos[k].x;
				maxx = minx + b;
			} else {
				minx = it->x;
				maxx = minx + b;
			}
			maxy = puntos[k].y > it->y ? puntos[k].y : it->y;
			miny = maxy - h;

			// Por cada candidato vemos si queda en la caja
			// formada por los dos puntos.
			vector<Point>::const_iterator it2 = candidatos.begin();
			for ( ; it2 != end; ++it2 ) {
				// Salteamos los dos puntos de referencia.
				if ( it == it2 ) continue;
				if ( adentro( *it2, minx, maxx, miny, maxy ) )
					res++;
			}

			if ( res > maximo.puntos ) {
				maximo.puntos = res;
				maximo.x = minx;
				maximo.y = miny;
			}
		}
	}

	return maximo;
}
